home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 February / PCWFEB09.iso / Software / Resources / Chat & Communication / Digsby build 37 / digsby_setup.exe / lib / oscar / rendezvous / peer.pyo (.txt) < prev    next >
Python Compiled Bytecode  |  2008-10-13  |  15KB  |  397 lines

  1. # Source Generated with Decompyle++
  2. # File: in.pyo (Python 2.5)
  3.  
  4. from util import autoassign, removedupes, Storage, myip, ip_from_bytes
  5. from util.observe import Observable
  6. from oscar.rendezvous.reactsocket import ReactSocketOne
  7. from common.timeoutsocket import TimeoutSocketMulti
  8. from common.timeoutsocket import iptuples
  9. from util.net import SocketEventMixin
  10. import struct
  11. import socket
  12. import oscar
  13. import time
  14. from logging import getLogger
  15. log = getLogger('oscar.peer')
  16. info = log.info
  17. from oscar.OscarUtil import tlv_list
  18. from oscar.rendezvous.proxy import ProxyHeader
  19. from pprint import pformat
  20. from common import pref
  21. from oscar.rendezvous.reactsocket import ReactSocket
  22. from oscar.rendezvous.rendezvous import rendezvous_message_types, rendezvous_tlvs, rendezvous_header
  23.  
  24. def handlech2(o, rendezvous_type, screenname, cookie, message_type, data):
  25.     IncomingOscarFileTransfer = IncomingOscarFileTransfer
  26.     import oscar.rendezvous.filetransfer
  27.     OscarDirectIM = OscarDirectIM
  28.     import oscar.rendezvous.directim
  29.     ChatInvite = ChatInvite
  30.     import oscar.rendezvous.chat
  31.     ch2dict = o.rdv_sessions
  32.     info('ch2 %s message from %s', rendezvous_type, screenname)
  33.     info('rendezvous_type = %r, screenname = %r, cookie = %r, message_type = %r, data = %r', rendezvous_type, screenname, cookie, message_type, data)
  34.     
  35.     try:
  36.         conn = ch2dict[cookie]
  37.         info('existing conn = %r', conn)
  38.     except KeyError:
  39.         if message_type == rendezvous_message_types.request:
  40.             factory = dict(file_xfer = IncomingOscarFileTransfer, direct_im = OscarDirectIM, chat_service = ChatInvite)[rendezvous_type]
  41.             ch2dict[cookie] = conn = factory(o, screenname, cookie)
  42.             info('new conn = %r', conn)
  43.         else:
  44.             return info('%s sent ch2 %s message, unknown RDV cookie', screenname, rendezvous_message_types[message_type])
  45.     except:
  46.         message_type == rendezvous_message_types.request
  47.  
  48.     conn.handlech2(message_type, data)
  49.  
  50. nullstr = '\x00' * 4
  51.  
  52. class OscarPeer(Observable):
  53.     
  54.     def __init__(self, protocol, screenname, cookie, capability):
  55.         Observable.__init__(self)
  56.         autoassign(self, locals())
  57.         self.buddy = protocol.buddies[screenname]
  58.         self.stage = 0
  59.         self.proxied = False
  60.         self.accepted = False
  61.  
  62.     
  63.     def handlech2(self, message_type, data):
  64.         info('message_type = %r, data = %r', message_type, data)
  65.         postfix = {
  66.             0: 'request',
  67.             1: 'cancel',
  68.             2: 'accept' }[message_type]
  69.         info('calling ch2' + postfix)
  70.         getattr(self, 'ch2' + postfix)(data)
  71.  
  72.     
  73.     def ch2request(self, data):
  74.         (rendtlvs, data) = oscar.unpack((('rendtlvs', 'named_tlvs', -1, rendezvous_tlvs),), data)
  75.         request_num = struct.unpack('!H', rendtlvs.request_num)[0]
  76.         info('rendtlvs = %r, data = %r, request_num = %r', rendtlvs, data, request_num)
  77.         if request_num == 1:
  78.             self.rendtlvs = rendtlvs
  79.             self.handle_request(rendtlvs)
  80.         elif request_num == 2:
  81.             info('received request num. 2: \n%s', pformat(rendtlvs))
  82.             if hasattr(rendtlvs, 'client_ip') and rendtlvs.client_ip == nullstr and rendtlvs.proxy_ip == nullstr:
  83.                 info('received a stage 3 request (\\x00\\x00\\x00\\x00)')
  84.                 info('connecting and sending an init_send to the proxy server')
  85.                 proxy_ip = pref('oscar.peer.proxy_server', 'ars.oscar.aol.com')
  86.                 self.stage = 3
  87.                 args = ([
  88.                     (proxy_ip, 5190)], self.initialize_proxy_send, self.failed)
  89.             elif hasattr(rendtlvs, 'proxy_flag'):
  90.                 info('receiver intervened with a stage 2 proxy')
  91.                 self.stage = 2
  92.                 self.grabaddrs(rendtlvs)
  93.                 self.needs_accept = True
  94.                 args = (self.ips, self.initialize_proxy_receive, self.failed)
  95.             else:
  96.                 info('received req num 2 redirect request')
  97.                 self.grabaddrs(rendtlvs)
  98.                 self.needs_accept = True
  99.                 if self.ips == []:
  100.                     log.warning(rendtlvs)
  101.                 
  102.                 args = (self.ips, self.successful_connection, self.sender_establishes_proxy)
  103.             (ips, success, error) = args
  104.             self.newsock(ips, success, error)
  105.         elif request_num == 3:
  106.             info('should try proxy now, request_num = 3')
  107.             self.rendtlvs = rendtlvs
  108.             ip = self.ips_from_rdv(rendtlvs)[0]
  109.             self.grabport(rendtlvs)
  110.             args = ([
  111.                 (ip, self.port)], self.initialize_proxy_receive, self.failed)
  112.             (ips, success, error) = args
  113.             self.newsock(ips, success, error)
  114.         
  115.  
  116.     
  117.     def failed(self):
  118.         log.error('nothing left to try.')
  119.  
  120.     
  121.     def establish_out_dc(self, message = '<HTML>', extratlvs = []):
  122.         info('message = %r, extratlvs = %r', message, extratlvs)
  123.         local_ip = pref('oscar.peer.local_ip', '')
  124.         if not local_ip:
  125.             local_ip = ''
  126.         
  127.         incoming_port = pref('oscar.peer.incoming_port', 0)
  128.         info('local_ip = %r, incoming_port = %r', local_ip, incoming_port)
  129.         proxy = pref('oscar.peer.always_proxy', None)
  130.         if proxy:
  131.             proxy = pref('oscar.peer.proxy_server', 'ars.oscar.aol.com')
  132.         
  133.         info('proxy = %r', proxy)
  134.         self.newsocket().tryaccept((local_ip, incoming_port), self.incoming_conn, (lambda : info('failed direct connection')), timeout = 0)
  135.         ip = myip()
  136.         (__, port) = self.socket.getsockname()
  137.         info('sending channel 2 request asking the receiver to connect to %s:%d', ip_from_bytes(ip), port)
  138.         self.send_ch2request(1, port, ip, proxy = proxy, message = message, extratlvs = extratlvs)
  139.  
  140.     
  141.     def establish_dc(self):
  142.         self.grabaddrs(self.rendtlvs)
  143.         info('establish_dc: potential ips %r', self.ips)
  144.         if hasattr(self.rendtlvs, 'proxy_flag'):
  145.             info('STAGE 1. sender sent proxy_flag. connecting to proxy server...')
  146.             self.stage = 1
  147.             success = self.initialize_proxy_receive
  148.             error = self.stage3_request
  149.             ips = self.ips
  150.         elif pref('oscar.peer.always_proxy', False):
  151.             info('STAGE 2: always_proxy is True')
  152.             self.stage = 2
  153.             ips = [
  154.                 pref('oscar.peer.proxy_server', 5190)]
  155.             success = self.initialize_proxy_send
  156.             error = self.error_proxy
  157.         else:
  158.             info('attempting direct connection to %r', self.ips)
  159.             ips = self.ips
  160.             self.needs_accept = True
  161.             success = self.successful_connection
  162.             error = self.try_redirect
  163.         self.newsock(ips, success, error)
  164.  
  165.     
  166.     def successful_connection(self):
  167.         log.info('successful connection')
  168.         if not self.accepted:
  169.             self.accepted = True
  170.             if getattr(self, 'needs_accept', False):
  171.                 info('needs_accept, sending accept')
  172.                 self.send_rdv('accept')
  173.             else:
  174.                 log.info('not sending accept packet, no "needs_accept"')
  175.             log.info('on_odc_connection')
  176.             self.on_odc_connection()
  177.         else:
  178.             log.info('not calling on_odc_connection, self.accepted is already True')
  179.  
  180.     
  181.     def ips_from_rdv(self, rtlvs):
  182.         if hasattr(rtlvs, 'proxy_flag'):
  183.             return [
  184.                 ipstr(rtlvs.proxy_ip)]
  185.         else:
  186.             return removedupes([
  187.                 ipstr(rtlvs.client_ip),
  188.                 ipstr(rtlvs.verified_ip)])
  189.  
  190.     
  191.     def initialize_proxy_send(self):
  192.         info('initialize_proxy_send, self.cookie = %r', self.cookie)
  193.         self.socket.receive_next(ProxyHeader._struct.size + 6, self.received_proxy_ack)
  194.         self.socket.push(ProxyHeader.initsend(self.protocol.self_buddy.name, self.cookie))
  195.  
  196.     
  197.     def initialize_proxy_receive(self):
  198.         info('sending proxy receive to %s:%d', self.socket.getpeername())
  199.         self.socket.receive_next(ProxyHeader, self.received_proxy_ready)
  200.         proxy_initrecv = ProxyHeader.initreceive(self.protocol.self_buddy.name, self.cookie, self.port)
  201.         self.socket.push(proxy_initrecv)
  202.  
  203.     
  204.     def received_proxy_ready(self, data):
  205.         (header, data) = ProxyHeader.unpack(data)
  206.         if header.command == ProxyHeader.commands.ready:
  207.             info('proxy READY received')
  208.             self.proxied = True
  209.             self.accepted = False
  210.             self.successful_connection()
  211.         elif header.command == ProxyHeader.commands.error:
  212.             log.error('Proxy server indicated ERROR!')
  213.             self.failed()
  214.         else:
  215.             raise AssertionError('Unknown proxy command: %d' % header.command)
  216.  
  217.     
  218.     def received_proxy_ack(self, data):
  219.         (header, data) = ProxyHeader.unpack(data)
  220.         if header.command == ProxyHeader.commands.ack:
  221.             info('received proxy ACK')
  222.             (proxyport, proxyip) = struct.unpack('!HI', data)
  223.             info('sending RDV request, req num %d', self.stage)
  224.             self.send_ch2request(self.stage, proxyport, None, proxyip)
  225.             self.socket.receive_next(ProxyHeader, self.received_proxy_ready)
  226.             self.needs_accept = False
  227.         else:
  228.             pformat = pformat
  229.             import pprint
  230.             log.error('Unexpected proxy packet: %r', pformat(list(iter(header))))
  231.             self.close()
  232.  
  233.     
  234.     def sender_establishes_proxy(self):
  235.         self.stage = 3
  236.         ips = [
  237.             (pref('oscar.peer.proxy_server'), 5190)]
  238.         info('sender_establishes_proxy, ips = %r', ips)
  239.         success = self.initialize_proxy_send
  240.         error = self.error_proxy
  241.         self.newsock(ips, success, error)
  242.  
  243.     
  244.     def error_proxy(self):
  245.         log.error('proxy server is being slow :(')
  246.  
  247.     
  248.     def stage3_request(self):
  249.         info('STAGE 3 - sending request...')
  250.         self.send_ch2request(2, port = None, client_ip = struct.pack('!I', 0), proxy = 0)
  251.  
  252.     
  253.     def try_redirect(self, e = None):
  254.         if getattr(self, '_done', False):
  255.             info('try_redirect was called but already done, so not asking for redirect.')
  256.             return None
  257.         
  258.         self.newsocket().tryaccept(('', 0), self.incoming_conn, self.stage3_request, 3)
  259.         (__, port) = self.socket.getsockname()
  260.         info('%r is trying a redirect, listening on port %d', self, port)
  261.         info('sending channel 2 request')
  262.         self.send_ch2request(2, port, myip())
  263.  
  264.     
  265.     def incoming_conn(self, socket):
  266.         info('obtained successful incoming connection')
  267.         self.socket = ReactSocket(socket, on_close = self.on_close)
  268.         self.needs_accept = False
  269.         self.successful_connection()
  270.  
  271.     
  272.     def grabport(self, rendtlvs):
  273.         if hasattr(rendtlvs, 'external_port'):
  274.             self.port = struct.unpack('!H', rendtlvs.external_port)[0]
  275.         
  276.  
  277.     
  278.     def grabaddrs(self, rendtlvs):
  279.         self.grabport(rendtlvs)
  280.         self.ips = [ (ip, self.port) for ip in rdv_ips(rendtlvs) ]
  281.  
  282.     
  283.     def channel2(self, rendezvous_data):
  284.         info('channel2: rendezvous_data = %r', rendezvous_data)
  285.         rdv_snac = oscar.snac.x04_x06(self.screenname, self.cookie, 2, rendezvous_data)
  286.         self.protocol.send_snac(*rdv_snac)
  287.  
  288.     
  289.     def send_rdv(self, type, data = ''):
  290.         info('sending RDV %s', type)
  291.         header = rendezvous_header(type, self.cookie, self.capability)
  292.         self.channel2(oscar.OscarUtil.tlv(5, header + data))
  293.  
  294.     
  295.     def send_ch2request(self, reqnum, port, client_ip, proxy = None, message = None, extratlvs = []):
  296.         info('send_ch2request, reqnum = %r, port = %r, client_ip = %r, proxy = %r, message = %r, extratlvs = %r', reqnum, port, client_ip, proxy, message, extratlvs)
  297.         if proxy and not isinstance(proxy, (int, long)):
  298.             proxy = struct.unpack('!I', socket.inet_aton(proxy))[0]
  299.         
  300.         rz = rendezvous_tlvs
  301.         tlvs = [
  302.             (rz.request_num, 2, reqnum)]
  303.         if proxy in (None, False):
  304.             tlvs += [
  305.                 (rz.mystery,)]
  306.         else:
  307.             tlvs += [
  308.                 (rz.proxy_ip, 4, proxy),
  309.                 (rz.proxy_ip_check, 4, ~proxy)]
  310.         if message is not None:
  311.             tlvs += [
  312.                 (rz.locale, 'en'),
  313.                 (rz.encoding, 'us-ascii'),
  314.                 (rz.user_message, message)]
  315.         
  316.         if client_ip is not None:
  317.             tlvs += [
  318.                 (rz.client_ip, client_ip)]
  319.         
  320.         if port is not None:
  321.             tlvs += [
  322.                 (rz.external_port, 2, port),
  323.                 (rz.port_check, 2, ~port)]
  324.         
  325.         if proxy not in (None, False):
  326.             tlvs += [
  327.                 (rz.proxy_flag,)]
  328.         
  329.         if extratlvs:
  330.             tlvs += extratlvs
  331.         
  332.         info(repr(tlvs))
  333.         self.send_rdv('request', tlv_list(*tlvs))
  334.  
  335.     
  336.     def newsock(self, ips, success, error):
  337.         if hasattr(self, 'socket'):
  338.             if isinstance(self.socket, SocketEventMixin):
  339.                 self.socket.unbind('socket_closed', self.on_close)
  340.             
  341.             
  342.             try:
  343.                 self.socket.getpeername()
  344.             except socket.error:
  345.                 e = None
  346.                 info(e)
  347.  
  348.             self.socket.close()
  349.             del self.socket
  350.         
  351.         
  352.         def assign_on_close(sock):
  353.             sock.bind_event('socket_closed', self.on_close)
  354.  
  355.         
  356.         def succ(sock):
  357.             sock.reassign()
  358.             self.socket = sock
  359.             success()
  360.  
  361.         TimeoutSocketMulti().tryconnect(iptuples(ips), succ, error, 2, cls = ReactSocketOne, provide_init = assign_on_close)
  362.  
  363.     
  364.     def newsocket(self):
  365.         if hasattr(self, 'socket'):
  366.             if isinstance(self.socket, SocketEventMixin):
  367.                 self.socket.unbind('socket_closed', self.on_close)
  368.             
  369.             
  370.             try:
  371.                 self.socket.getpeername()
  372.             except socket.error:
  373.                 e = None
  374.                 info(e)
  375.  
  376.             self.socket.close()
  377.             if isinstance(self.socket, ReactSocket):
  378.                 self.socket.cancel_timeout()
  379.             
  380.             del self.socket
  381.         
  382.         self.socket = newsock = ReactSocket(on_close = self.on_close)
  383.         info('newsocket: %r', newsock)
  384.         return newsock
  385.  
  386.  
  387. ipstr = ip_from_bytes
  388.  
  389. def rdv_ips(rendtlvs):
  390.     normal_order = ('client_ip', 'verified_ip', 'proxy_ip')
  391.     proxy_order = ('proxy_ip', 'client_ip', 'verified_ip')
  392.     order = None if hasattr(rendtlvs, 'proxy_flag') else normal_order
  393.     
  394.     ipif = lambda s: None if hasattr(rendtlvs, s) else None
  395.     return None([]([], [ ipif(s) for s in order ]))
  396.  
  397.